﻿using FANUC.DTO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Description;

namespace FANUC.Controllers
{
    public class TodayRobotStateDistributionController : ApiController
    {
        private FANUCDB db = new FANUCDB();

        [ResponseType(typeof(TodayRobotStateDistributionDtoOutput))]
        public IHttpActionResult Get(int id)
        {
            //当天00:00:00
            DateTime today0 = System.DateTime.Now.Date;
            //此机器人当天第一个状态;-1:default,1:PowerOff,2:Fault,3:Ready,4:Running
            int firstState, lastState = -1;
            //第一次发生事件改变的时间点
            DateTime todayFirstChangeTime;
            //当前时间点
            DateTime now = System.DateTime.Now;

            //此机器人当天0点开始第一个变化记录，FANUC会在0点插入一条最新机器人的状态
            var todayFirstChangeRecord = db.Robot_State_Change_History.Where(a => a.ChangeDateTime >= today0 && a.Robot_ID == id).OrderBy(a => a.ChangeDateTime).FirstOrDefault();
            if (todayFirstChangeRecord == null)
            {
                todayFirstChangeTime = today0;
                firstState = 1;
            }
            else
            {
                todayFirstChangeTime = todayFirstChangeRecord.ChangeDateTime;
                firstState = todayFirstChangeRecord.Changed_State_Type;
            }

            List<Robot_State_Change_History> allStateChangeRecords = db.Robot_State_Change_History.Where(a => a.ChangeDateTime > todayFirstChangeTime && a.Robot_ID == id).ToList();
            //按状态合计各状态时间(分钟)
            var stateGroupSumByState = from a in allStateChangeRecords group a by new { a.Original_State_Type } into grp select new { grp.Key.Original_State_Type, TotalMinutes = grp.Sum(a => a.Period)/60 };

            //获取当天最后一个机器人状态
            var todayLastChangeRecord = db.Robot_State_Change_History.Where(a => a.ChangeDateTime > today0 && a.Robot_ID == id).OrderByDescending(a => a.ChangeDateTime).FirstOrDefault();
            DateTime lastChangeTime;
            if (todayLastChangeRecord == null)
            {
                lastState = 1;
                lastChangeTime = now;
            }
            else
            {
                lastState = todayLastChangeRecord.Changed_State_Type;
                lastChangeTime = todayLastChangeRecord.ChangeDateTime;
            }

            int todayTotalMinutes = Convert.ToInt16((now - today0).TotalMinutes);

            var todayTotalRunningSum = stateGroupSumByState.Where(a => a.Original_State_Type == 4).FirstOrDefault();
            int todayTotalRunningMinutes = Convert.ToInt16(todayTotalRunningSum == null ? 0 : todayTotalRunningSum.TotalMinutes) + (lastState == 4 ? Convert.ToInt16((now - lastChangeTime).TotalMinutes) : 0);
            decimal runningRatio = Convert.ToDecimal(todayTotalRunningMinutes) / todayTotalMinutes;

            var todayTotalReadySum = stateGroupSumByState.Where(a => a.Original_State_Type == 3).FirstOrDefault();
            int todayTotalReadyMinutes = Convert.ToInt16(todayTotalReadySum == null ? 0 : todayTotalReadySum.TotalMinutes) + (lastState == 3 ? Convert.ToInt16((now - lastChangeTime).TotalMinutes) : 0);
            decimal readyRatio = Convert.ToDecimal(todayTotalReadyMinutes) / todayTotalMinutes;

            var todayTotalFaultSum = stateGroupSumByState.Where(a => a.Original_State_Type == 2).FirstOrDefault();
            int todayTotalFaultMinutes = Convert.ToInt16(todayTotalFaultSum == null ? 0 : todayTotalFaultSum.TotalMinutes) + (lastState == 2 ? Convert.ToInt16((now - lastChangeTime).TotalMinutes) : 0);
            decimal faultRatio = Convert.ToDecimal(todayTotalFaultMinutes) / todayTotalMinutes;

            decimal powerOffRatio = 1 - runningRatio - readyRatio - faultRatio;

            TodayRobotStateDistributionDtoOutput stateDistribution = new TodayRobotStateDistributionDtoOutput();
            stateDistribution.RunningtRatio = decimal.Round(runningRatio, 4);
            stateDistribution.FaultRatio = decimal.Round(faultRatio, 4);
            stateDistribution.ReadyRatio = decimal.Round(readyRatio, 4);
            stateDistribution.PowerOffRatio = decimal.Round(powerOffRatio, 4);
            stateDistribution.RobotID = id.ToString();
            return Ok(stateDistribution);
        }

        [ApiExplorerSettings(IgnoreApi = true)]
        public string Options()
        { return null; }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
